/************************************************************************************
**  
* @copyright (c) 2015-, Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file     duye_cap_filter.h
* @version     
* @brief      
* @author   
* @date     2013-01-09
* @note 
*
*  1. 2018-01-09 created this file
* 
*/
#pragma once

#include <list>
#include <duye_cap_packet.h>
#include <duye_cap_protocol.h>

namespace duye {

/**
 * @brief ip and port pair, IPPortPair<ip, port>
 */
typedef std::pair<uint32, uint16> IPPortPair;

/**
 * @brief port range pair, PortRangePair<minPort, maxPort>
 */
typedef std::pair<uint16, uint16> PortRangePair;

/**
 * @brief port range pair, IPRangePair<minIP, maxIP>
 */
typedef std::pair<uint32, uint32> IPRangePair;

class RuleItem;

typedef std::list<RuleItem> RuleItemList;

class FilterWorker;

/**
 * @brief filter rule
 */
class FilterRule {
public:
    FilterRule();
	~FilterRule();
    
    void addWhiteRule(const RuleItem& ruleItem);
    void addBlackRule(const RuleItem& ruleItem);

	const RuleItemList& whiteRuleList() const;
	const RuleItemList& blackRuleList() const;

	void setFilterWorker(FilterWorker* filterWorker);
	FilterWorker* getFilterWorker();

	bool hasFilterRule() const;

private:
    RuleItemList m_whiteRuleList;
	RuleItemList m_blackRuleList;
	FilterWorker* m_filterWorker;
};

/**
 * @brief rule item
 */
class RuleItem {
public:
    RuleItem();
    ~RuleItem();

    void setProtocol(const ProtocolType& protocol);
    const ProtocolType& protocol() const;
    
    void setSrcIPAddr(const uint32 ip);
    uint32 srcIPAddr() const;
    
    void setDstIPAddr(const uint32 ip);
    uint32 dstIPAddr() const;

    void setSrcPort(const uint16 port);
    uint16 srcPort() const;
    
    void setDstPort(const uint16 port);
    uint16 dstPort() const;	

    void setSrcIPRange(const IPRangePair& portRange);
    const IPRangePair& srcIPRange() const;      

    void setDstIPRange(const IPRangePair& portRange);
    const IPRangePair& dstIPRange() const;       
    
    void setSrcPortRange(const PortRangePair& portRange);
    const PortRangePair& srcPortRange() const;  

    void setDstPortRange(const PortRangePair& portRange);
    const PortRangePair& dstPortRange() const; 

	bool hasProtoFilter() const;
	bool hasIPAddrFilter() const;
	bool hasRangeIPAddrFilter() const;
	bool hasPortFilter() const;
	bool hasRangePortFilter() const;

private:
    ProtocolType m_protocol;
    uint32 m_srcIPAddr;
    uint32 m_dstIPAddr;
	uint16 m_srcPort;
	uint16 m_dstPort;
    IPRangePair m_srcIPRange;
    IPRangePair m_dstIPRange;    
    PortRangePair m_srcPortRange;
    PortRangePair m_dstPortRange;    

	bool m_hasProtoFilter;
	bool m_hasIPAddrFilter;
	bool m_hasRangeIPAddrFilter;
	bool m_hasPortFilter;
	bool m_hasRangePortFilter;
};

/**
 * @brief filter base class
 */
class FilterWorker {
public:
	virtual ~FilterWorker() {}
	virtual bool filterPkt(const PacketReference& pktRef, const FilterRule& rule) = 0;
};

}
